package io.kimmking.statemachine02;

import org.squirrelframework.foundation.fsm.StateMachineBuilderFactory;
import org.squirrelframework.foundation.fsm.UntypedStateMachine;
import org.squirrelframework.foundation.fsm.UntypedStateMachineBuilder;
import org.squirrelframework.foundation.fsm.annotation.*;
import org.squirrelframework.foundation.fsm.impl.AbstractUntypedStateMachine;

@States({
        @State(name = "A", entryCallMethod = "entry", exitCallMethod = "exit", initialState = true),
        @State(name = "B", entryCallMethod = "entry", exitCallMethod = "exit"),
        @State(name = "C", entryCallMethod = "entry", exitCallMethod = "exit"),
        @State(name = "D", entryCallMethod = "entry", exitCallMethod = "exit", isFinal = true)
})
@Transitions({
        @Transit(from = "A", to = "B", on = "ATOB", callMethod = "to"),
        @Transit(from = "B", to = "C", on = "BTOC", callMethod = "to"),
        @Transit(from = "C", to = "D", on = "CTOD", callMethod = "to")
})
@StateMachineParameters(stateType = DeclarativeMachine.MyState.class, eventType = DeclarativeMachine.MyEvent.class, contextType = DeclarativeMachine.MyContext.class)
public class DeclarativeMachine extends AbstractUntypedStateMachine {

    public void entry(MyState from, MyState to, MyEvent on, MyContext context){
        System.out.println("---entry: to-" + to);
    }

    public void exit(MyState from, MyState to, MyEvent on, MyContext context){
        System.out.println("---exit: from-" + from);
    }

    public void to(MyState from, MyState to, MyEvent on, MyContext context){
        System.out.println("---to: from-" + from+" to-" + to);
    }

    public class MyContext{
        public Object value;
    }
    public enum MyState{
        A,B,C,D
    }
    public enum MyEvent{
        ATOB,BTOC,CTOD
    }

    public static void main(String[] args) {
        UntypedStateMachineBuilder builder = StateMachineBuilderFactory.create(DeclarativeMachine.class);
        UntypedStateMachine fsm = builder.newAnyStateMachine(MyState.A);
        fsm.start();
        fsm.fire(MyEvent.ATOB);
        fsm.fire(MyEvent.BTOC);
        fsm.fire(MyEvent.CTOD);
    }

}

